﻿Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.VersionControl.Client
Imports Microsoft.TeamFoundation
Imports System.Globalization
Imports System.IO

Module QuickShelve
    Sub Main()
        Dim fallbackCredentialsProvider As ICredentialsProvider
        fallbackCredentialsProvider = New UICredentialsProvider()

        For Each serverName In GetServerNames()
            Dim server As TeamFoundationServer
            server = TeamFoundationServerFactory.GetServer(serverName, fallbackCredentialsProvider)

            Try
                server.EnsureAuthenticated()
            Catch ex As System.Net.WebException
                'This will occur if the server cannot be contacted. Log it and move on.
                My.Application.Log.WriteException(ex)
                Continue For
            Catch ex As TeamFoundationServerUnauthorizedException
                'This will occur if the user cancels the authentication dialog. Log it and move on.
                My.Application.Log.WriteException(ex)
                Continue For
            End Try

            For Each workspace In GetWorkspaces(server)
                ShelvePendingChanges(workspace)
            Next
        Next
    End Sub

    Private Function GetServerNames() As IEnumerable(Of String)
        Dim registeredServerNames As New List(Of String)

        For Each registeredServer In RegisteredServers.GetServers()
            registeredServerNames.Add(registeredServer.Name)
        Next

        Return registeredServerNames
    End Function

    Private Function GetWorkspaces(ByVal server As TeamFoundationServer) As IEnumerable(Of Workspace)
        Dim versionControlServer As VersionControlServer
        versionControlServer = DirectCast(server.GetService(GetType(VersionControlServer)), VersionControlServer)

        Dim workspaces As Workspace()
        workspaces = versionControlServer.QueryWorkspaces(Nothing, server.AuthenticatedUserName, Environment.MachineName)

        Return workspaces
    End Function

    Private Sub ShelvePendingChanges(ByVal workspace As Workspace)
        Dim pendingChanges As PendingChange()
        pendingChanges = workspace.GetPendingChanges()

        If pendingChanges.Length > 0 Then
            Dim shelveset As Shelveset
            shelveset = GetShelveset(workspace)

            Try
                workspace.Shelve(shelveset, pendingChanges, ShelvingOptions.Replace)
            Catch ex As FileNotFoundException
                'This will occur if a file that has a pending change no longer exists. Log it.
                My.Application.Log.WriteException(ex)
            End Try
        End If
    End Sub

    Private Function GetShelveset(ByVal workspace As Workspace) As Shelveset
        Dim versionControlServer As VersionControlServer
        versionControlServer = workspace.VersionControlServer

        Dim workspaceName As String
        workspaceName = workspace.Name

        Dim workspaceOwner As String
        workspaceOwner = versionControlServer.TeamFoundationServer.AuthenticatedUserName

        Dim shelvesetName As String
        shelvesetName = String.Format(CultureInfo.CurrentCulture, "QuickShelve of {0}", workspaceName, workspaceOwner)

        Return New Shelveset(versionControlServer, shelvesetName, workspaceOwner)
    End Function
End Module